package equipment.finger;

import java.io.IOException;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;

public class Finger_tool {

	
	//指纹设备采集接口
    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)Native.loadLibrary("ZKFPCap",CLibrary.class);
        
        int sensorInit();    //指纹仪器初始化，成功返回0
        int sensorOpen(int index);    //链接指纹仪器返回>0指纹采集仪句柄，返回0失败
        int sensorFree();   //释放仪器初始化使用的空间,返回0
        int sensorGetCount();    //获取链接数量
        int sensorClose();   //断开连接释放空间
        int sensorCapture(int handle, byte[] imageBuffer, int imageBufferSize);    //获得菜鸡的图像
        
        int sensorGetParameter(int handle, int paramcode);   //获取设备参数(图像高度1，图像宽度2，图像buffer106)
        int sensorGetParameterEx(int handle, int paramcode, Pointer pramvlue, int[] pramlen);  //获取设备参数(制造商名称1101，采集器名称1102，序列号1103)
        int sensorGetVersion(Pointer version, int len);   //获取设备版本号
    }
    
    //指纹接口算法库
    public interface ZKFCLibrary extends Library {
    	ZKFCLibrary zkf = (ZKFCLibrary)Native.loadLibrary("ZKFinger10",ZKFCLibrary.class);
    	
    	int BIOKEY_INIT(int license, Pointer isize, Pointer pram, Pointer buffer, int imageflag);  //初始换算法库
    	int BIOKEY_CLOSE(int handle);  
    	int BIOKEY_SET_PARAMETER(int license, int paramcode, int paramvalue);  //设置指纹偏移角度(paramcode为4，paramvalue为0~180)
    	int BIOKEY_EXTRACT(int license, byte[] pBuffer, byte[] pTemplate, int PurposeMode);    //从指纹图像中提取指纹模版
    	int BIOKEY_IDENTIFYTEMP(int license, byte[] template, int[] fingId, int[] score);   //1:n对比
    	int BIOKEY_VERIFY(int license, byte[] fingerTemp, byte[] template);   //1：1对比
    }
	
	
	
	
	public static byte[] changeByte(int data) {
		byte b4 = (byte) ((data) >> 24);
		byte b3 = (byte) (((data) << 8) >> 24);
		byte b2 = (byte) (((data) << 16) >> 24);
		byte b1 = (byte) (((data) << 24) >> 24);
		byte[] bytes = { b1, b2, b3, b4 };
		return bytes;
	}
    
    public static void writeBitmap(byte[] imageBuf, int nWidth, int nHeight,
			String path) throws IOException {
		java.io.FileOutputStream fos = new java.io.FileOutputStream(path);
		java.io.DataOutputStream dos = new java.io.DataOutputStream(fos);

		int bfType = 0x424d; // 位图文件类型（0—1字节）
		int bfSize = 54 + 1024 + nWidth * nHeight;// bmp文件的大小（2—5字节）
		int bfReserved1 = 0;// 位图文件保留字，必须为0（6-7字节）
		int bfReserved2 = 0;// 位图文件保留字，必须为0（8-9字节）
		int bfOffBits = 54 + 1024;// 文件头开始到位图实际数据之间的字节的偏移量（10-13字节）

		dos.writeShort(bfType); // 输入位图文件类型'BM'
		dos.write(changeByte(bfSize), 0, 4); // 输入位图文件大小
		dos.write(changeByte(bfReserved1), 0, 2);// 输入位图文件保留字
		dos.write(changeByte(bfReserved2), 0, 2);// 输入位图文件保留字
		dos.write(changeByte(bfOffBits), 0, 4);// 输入位图文件偏移量

		int biSize = 40;// 信息头所需的字节数（14-17字节）
		int biWidth = nWidth;// 位图的宽（18-21字节）
		int biHeight = nHeight;// 位图的高（22-25字节）
		int biPlanes = 1; // 目标设备的级别，必须是1（26-27字节）
		int biBitcount = 8;// 每个像素所需的位数（28-29字节），必须是1位（双色）、4位（16色）、8位（256色）或者24位（真彩色）之一。
		int biCompression = 0;// 位图压缩类型，必须是0（不压缩）（30-33字节）、1（BI_RLEB压缩类型）或2（BI_RLE4压缩类型）之一。
		int biSizeImage = nWidth * nHeight;// 实际位图图像的大小，即整个实际绘制的图像大小（34-37字节）
		int biXPelsPerMeter = 0;// 位图水平分辨率，每米像素数（38-41字节）这个数是系统默认值
		int biYPelsPerMeter = 0;// 位图垂直分辨率，每米像素数（42-45字节）这个数是系统默认值
		int biClrUsed = 0;// 位图实际使用的颜色表中的颜色数（46-49字节），如果为0的话，说明全部使用了
		int biClrImportant = 0;// 位图显示过程中重要的颜色数(50-53字节)，如果为0的话，说明全部重要

		dos.write(changeByte(biSize), 0, 4);// 输入信息头数据的总字节数
		dos.write(changeByte(biWidth), 0, 4);// 输入位图的宽
		dos.write(changeByte(biHeight), 0, 4);// 输入位图的高
		dos.write(changeByte(biPlanes), 0, 2);// 输入位图的目标设备级别
		dos.write(changeByte(biBitcount), 0, 2);// 输入每个像素占据的字节数
		dos.write(changeByte(biCompression), 0, 4);// 输入位图的压缩类型
		dos.write(changeByte(biSizeImage), 0, 4);// 输入位图的实际大小
		dos.write(changeByte(biXPelsPerMeter), 0, 4);// 输入位图的水平分辨率
		dos.write(changeByte(biYPelsPerMeter), 0, 4);// 输入位图的垂直分辨率
		dos.write(changeByte(biClrUsed), 0, 4);// 输入位图使用的总颜色数
		dos.write(changeByte(biClrImportant), 0, 4);// 输入位图使用过程中重要的颜色数

		for (int i = 0; i < 256; i++) {
			dos.writeByte(i);
			dos.writeByte(i);
			dos.writeByte(i);
			dos.writeByte(0);
		}

		dos.write(imageBuf, 0, nWidth * nHeight);
		dos.flush();
		dos.close();
		fos.close();
	}
	
	public static int capture(int devHandle, byte[] imageBuffer,
			int imageBufferSize) throws InterruptedException{
		
		while (true) {
			int ret = CLibrary.INSTANCE.sensorCapture(devHandle, imageBuffer,imageBufferSize);
			if (ret > 0) {
				System.out.println("采集到一个图像!");
				return ret;
			}
			Thread.sleep(30);
		}
	}
	
}
